package com.ty.typehandler;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import lombok.SneakyThrows;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class JsonTypeHandler<T> extends BaseTypeHandler<T> {

    static   ObjectMapper objectMapper = new ObjectMapper();
    private JavaType javaType; //它用于表示 Java 类型的元信息，包括泛型类型、数组类型、集合类型等复杂类型的结构

    static {
        // 把泛型外部和内部全类型包含在json数据里面，反序列化的时候就可以找到真实的类型，解决了java泛型擦除
        objectMapper.activateDefaultTyping(objectMapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL);

    }
    public JsonTypeHandler() {}

    public JsonTypeHandler(Class<T> clazz)
    {
        this.javaType =  TypeFactory.defaultInstance().constructType(clazz);
    }
    @Override // java 对象属性 -> mysql 字段   序列化
    @SneakyThrows
    public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
        String json  = objectMapper.writeValueAsString(parameter); //包含了全类名
        ps.setString(i, json);
    }

    @Override //mysql 字段值 -》  java 对象属性值   反序列化
    @SneakyThrows
    public T getNullableResult(ResultSet rs, String columnName) throws SQLException {
        //rs.getString(columnName) mysql 数据库字段的值
        if(rs.getString(columnName) == null){
            return null;
        }
        return objectMapper.readValue(rs.getString(columnName),this.javaType);
    }

    @Override
    public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return null;
    }

    @Override
    public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return null;
    }
}
